package com.adk.backend.service.impl;

import com.adk.backend.entity.LxInventoryList;
import com.adk.backend.entity.LxTransferList;
import com.adk.backend.entity.LxTransferDetails;
import com.adk.backend.mapper.InventoryListMapper;
import com.adk.backend.mapper.TransferListMapper;
import com.adk.backend.mapper.TransferDetailsMapper;
import com.adk.backend.service.InventoryListService;
import com.adk.backend.util.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Calendar;
import java.util.Date;

/**
 * 库存列表服务实现类
 */
@Slf4j
@Service
public class InventoryListServiceImpl implements InventoryListService {
    
    @Autowired
    private InventoryListMapper inventoryListMapper;
    
    @Autowired
    private TransferListMapper transferListMapper;
    
    @Autowired
    private TransferDetailsMapper transferDetailsMapper;
    
    @Autowired
    private ExcelUtil excelUtil;
    
    @Override
    public List<Map<String, Object>> getInventoryList(Map<String, Object> params) {
        return inventoryListMapper.selectInventoryListByCondition(params);
    }
    
    @Override
    public Map<String, Object> getInventoryDetailById(Long id) {
        return inventoryListMapper.selectInventoryDetailById(id);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveInventory(LxInventoryList inventory) {
        try {
            int currentTime = (int) (System.currentTimeMillis() / 1000);
            
            if (inventory.getId() != null && inventory.getId() > 0) {
                // 更新
                inventory.setUpdateTime(currentTime);
                inventoryListMapper.updateById(inventory);
            } else {
                // 新增
                if (inventory.getAddTime() == null) {
                    inventory.setAddTime(currentTime);
                }
                if (inventory.getQty() == null) {
                    inventory.setQty(0);
                }
                if (inventory.getOQty() == null) {
                    inventory.setOQty(inventory.getQty());
                }
                if (inventory.getIsOb() == null) {
                    inventory.setIsOb(0);
                }
                inventoryListMapper.insert(inventory);
            }
            return true;
        } catch (Exception e) {
            log.error("保存库存失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveInventoryFromRefs(Map<String, Object> data) {
        return saveInventoryFromRefs(data, null);
    }
    
    /**
     * 保存库存（从引用代码转换，带用户ID）
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveInventoryFromRefs(Map<String, Object> data, Integer userId) {
        try {
            int currentTime = (int) (System.currentTimeMillis() / 1000);
            
            // 获取引用代码
            String eanCode = data.get("eanCode") != null ? data.get("eanCode").toString().trim() : "";
            String whRef = data.get("whRef") != null ? data.get("whRef").toString().trim() : "";
            String vndRef = data.get("vndRef") != null ? data.get("vndRef").toString().trim() : "";
            
            // 转换为ID
            Map<String, Object> product = inventoryListMapper.selectProductIdByEanCode(eanCode);
            if (product == null || product.get("id") == null) {
                throw new RuntimeException("EAN/UPC代码不存在: " + eanCode);
            }
            
            Map<String, Object> warehouse = inventoryListMapper.selectWarehouseIdByWhRef(whRef);
            if (warehouse == null || warehouse.get("id") == null) {
                throw new RuntimeException("仓库引用代码不存在: " + whRef);
            }
            
            Map<String, Object> vendor = inventoryListMapper.selectVendorIdByVndRef(vndRef);
            if (vendor == null || vendor.get("id") == null) {
                throw new RuntimeException("供应商引用代码不存在: " + vndRef);
            }
            
            Long proId = ((Number) product.get("id")).longValue();
            Long whId = ((Number) warehouse.get("id")).longValue();
            Long vndId = ((Number) vendor.get("id")).longValue();
            
            // 创建库存对象
            LxInventoryList inventory = new LxInventoryList();
            
            // 处理ID（更新时需要）
            Object idObj = data.get("id");
            if (idObj != null) {
                Long id = Long.valueOf(idObj.toString());
                if (id > 0) {
                    inventory.setId(id);
                }
            }
            
            inventory.setProId(proId);
            inventory.setWhId(whId);
            inventory.setVndId(vndId);
            
            // 处理其他字段（先处理，因为数量计算可能依赖这些字段）
            if (data.get("ibNo") != null) {
                inventory.setIbNo(data.get("ibNo").toString());
            }
            if (data.get("palletNo") != null) {
                inventory.setPalletNo(data.get("palletNo").toString());
            }
            if (data.get("batchCode") != null) {
                inventory.setBatchCode(data.get("batchCode").toString());
            }
            if (data.get("batchDate") != null) {
                String batchDateStr = data.get("batchDate").toString();
                inventory.setBatchDate(batchDateStr);
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    Date batchDate = sdf.parse(batchDateStr);
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(batchDate);
                    inventory.setBatchYear(cal.get(Calendar.YEAR));
                } catch (Exception e) {
                    inventory.setIsFresh(6);
                }
            }
            if (data.get("ctn") != null) {
                inventory.setCtn(Integer.valueOf(data.get("ctn").toString()));
            }
            if (data.get("ctnPcs") != null) {
                inventory.setCtnPcs(Integer.valueOf(data.get("ctnPcs").toString()));
            }
            if (data.get("ibRef") != null) {
                inventory.setIbRef(data.get("ibRef").toString());
            }
            if (data.get("remarks") != null) {
                inventory.setRemarks(data.get("remarks").toString());
            }
            
            // 处理数量（与PHP逻辑一致）
            Object qtyObj = data.get("qty");
            int qty = 0;
            if (qtyObj != null) {
                qty = Integer.valueOf(qtyObj.toString());
            }
            
            // 如果qty < 1 且 ctn > 0 且 ctnPcs > 0，则使用 ctn * ctnPcs（与PHP逻辑一致）
            if (qty < 1 && inventory.getCtn() != null && inventory.getCtn() > 0 
                && inventory.getCtnPcs() != null && inventory.getCtnPcs() > 0) {
                qty = inventory.getCtn() * inventory.getCtnPcs();
            }
            
            // 如果是更新，需要累加数量（与PHP逻辑一致）
            // 注意：PHP逻辑中，如果qty < 1且ctn > 0且ctnPcs > 0，则直接使用ctn * ctnPcs，不再累加
            if (inventory.getId() != null && inventory.getId() > 0) {
                // 获取现有库存的数量
                LxInventoryList existing = inventoryListMapper.selectById(inventory.getId());
                if (existing != null) {
                    // 如果qty < 1且ctn > 0且ctnPcs > 0，则直接使用ctn * ctnPcs（不再累加）
                    // 否则累加数量（与PHP逻辑一致：$info['qty'] = intval($v[1])+intval($check_exists['qty']);）
                    Object originalQtyObj = data.get("qty");
                    int originalQty = 0;
                    if (originalQtyObj != null) {
                        originalQty = Integer.valueOf(originalQtyObj.toString());
                    }
                    
                    if (originalQty < 1 && inventory.getCtn() != null && inventory.getCtn() > 0 
                        && inventory.getCtnPcs() != null && inventory.getCtnPcs() > 0) {
                        // 直接使用ctn * ctnPcs，不累加
                        inventory.setQty(qty);
                        inventory.setOQty(qty);
                    } else {
                        // 累加数量
                        inventory.setQty(existing.getQty() + qty);
                        inventory.setOQty(existing.getOQty() + qty);
                    }
                } else {
                    inventory.setQty(qty);
                    inventory.setOQty(qty);
                }
            } else {
                inventory.setQty(qty);
                inventory.setOQty(qty);
            }
            
            // 保存
            if (inventory.getId() != null && inventory.getId() > 0) {
                // 更新：设置add_uid和add_time（与PHP逻辑一致：$info['add_uid'] = $_SESSION['userid']; $info['add_time'] = $timers;）
                if (userId != null) {
                    inventory.setAddUid(userId.longValue());
                }
                inventory.setAddTime(currentTime);
                inventoryListMapper.updateById(inventory);
            } else {
                // 新增
                inventory.setAddTime(currentTime);
                if (userId != null) {
                    inventory.setAddUid(userId.longValue());
                }
                if (inventory.getIsOb() == null) {
                    inventory.setIsOb(0);
                }
                inventoryListMapper.insert(inventory);
            }
            
            return true;
        } catch (Exception e) {
            log.error("保存库存失败", e);
            throw e;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteInventory(Long id) {
        try {
            inventoryListMapper.deleteById(id);
            return true;
        } catch (Exception e) {
            log.error("删除库存失败", e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importInventoryFromExcel(MultipartFile file, Integer userId) {
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "");
        
        try {
            // 读取Excel文件
            List<List<String>> data = excelUtil.readExcel(file);
            
            if (data == null || data.size() < 2) {
                result.put("message", "Excel文件为空或格式不正确");
                return result;
            }
            
            int currentTime = (int) (System.currentTimeMillis() / 1000);
            String errMsg = null;
            
            // 第一遍检查：验证数据有效性
            for (int k = 1; k < data.size(); k++) {
                List<String> row = data.get(k);
                if (row == null || row.size() < 12) {
                    continue;
                }
                
                String eanCode = row.get(0) != null ? row.get(0).trim().replace("'", "") : "";
                String qtyStr = row.get(1) != null ? row.get(1).trim() : "0";
                String whRef = row.get(2) != null ? row.get(2).trim() : "";
                String ibNo = row.get(3) != null ? row.get(3).trim() : "";
                String palletNo = row.get(4) != null ? row.get(4).trim() : "";
                String vndRef = row.get(5) != null ? row.get(5).trim() : "";
                String batchCode = row.get(6) != null ? row.get(6).trim() : "";
                
                // 检查入库单号是否为空
                if (ibNo.isEmpty()) {
                    errMsg = "Line " + (k + 1) + ", Inbound Number is empty.";
                    break;
                }
                
                // 检查数量是否小于0
                int qty = 0;
                try {
                    qty = Integer.parseInt(qtyStr);
                    if (qty < 0) {
                        errMsg = "Line " + (k + 1) + ", Qty: " + qty + " Less than 0.";
                        break;
                    }
                } catch (NumberFormatException e) {
                    errMsg = "Line " + (k + 1) + ", Qty is not a valid number.";
                    break;
                }
                
                // 检查产品是否存在
                Map<String, Object> product = inventoryListMapper.selectProductIdByEanCode(eanCode);
                if (product == null || product.get("id") == null) {
                    errMsg = "Line " + (k + 1) + ", EAN/UPC_Code: " + eanCode + " not found.";
                    break;
                }
                
                // 检查仓库是否存在
                Map<String, Object> warehouse = inventoryListMapper.selectWarehouseIdByWhRef(whRef);
                if (warehouse == null || warehouse.get("id") == null) {
                    errMsg = "Line " + (k + 1) + ", Warehouse Ref: " + whRef + " not found.";
                    break;
                }
                
                // 检查供应商是否存在
                Map<String, Object> vendor = inventoryListMapper.selectVendorIdByVndRef(vndRef);
                if (vendor == null || vendor.get("id") == null) {
                    errMsg = "Line " + (k + 1) + ", Vendor Ref: " + vndRef + " not found.";
                    break;
                }
                
                // 检查是否已存在（qty > 0）
                Long proId = ((Number) product.get("id")).longValue();
                Long whId = ((Number) warehouse.get("id")).longValue();
                Long vndId = ((Number) vendor.get("id")).longValue();
                
                QueryWrapper<LxInventoryList> wrapper = new QueryWrapper<>();
                wrapper.eq("pro_id", proId)
                        .eq("ib_no", ibNo)
                        .eq("pallet_no", palletNo)
                        .eq("batch_code", batchCode)
                        .gt("qty", 0);
                
                LxInventoryList existing = inventoryListMapper.selectOne(wrapper);
                if (existing != null) {
                    errMsg = "Line " + (k + 1) + ", EAN/UPC_Code: " + eanCode + ", Inbound Number: " + ibNo + 
                            ", Pallet Number: " + palletNo + ", Batch Code: " + batchCode + " already imported.";
                    break;
                }
            }
            
            if (errMsg != null) {
                result.put("message", errMsg);
                return result;
            }
            
            // 第二遍处理：导入数据
            for (int k = 1; k < data.size(); k++) {
                List<String> row = data.get(k);
                if (row == null || row.size() < 12) {
                    continue;
                }
                
                String eanCode = row.get(0) != null ? row.get(0).trim().replace("'", "") : "";
                String qtyStr = row.get(1) != null ? row.get(1).trim() : "0";
                String whRef = row.get(2) != null ? row.get(2).trim() : "";
                String ibNo = row.get(3) != null ? row.get(3).trim() : "";
                String palletNo = row.get(4) != null ? row.get(4).trim() : "";
                String vndRef = row.get(5) != null ? row.get(5).trim() : "";
                String batchCode = row.get(6) != null ? row.get(6).trim() : "";
                String batchDateStr = row.size() > 7 ? (row.get(7) != null ? row.get(7).trim() : "") : "";
                String ctnStr = row.size() > 8 ? (row.get(8) != null ? row.get(8).trim() : "0") : "0";
                String ctnPcsStr = row.size() > 9 ? (row.get(9) != null ? row.get(9).trim() : "0") : "0";
                String ibRef = row.size() > 10 ? (row.get(10) != null ? row.get(10).trim() : "") : "";
                String remarks = row.size() > 11 ? (row.get(11) != null ? row.get(11).trim() : "") : "";
                
                Map<String, Object> product = inventoryListMapper.selectProductIdByEanCode(eanCode);
                Map<String, Object> warehouse = inventoryListMapper.selectWarehouseIdByWhRef(whRef);
                Map<String, Object> vendor = inventoryListMapper.selectVendorIdByVndRef(vndRef);
                
                Long proId = ((Number) product.get("id")).longValue();
                Long whId = ((Number) warehouse.get("id")).longValue();
                Long vndId = ((Number) vendor.get("id")).longValue();
                
                int qty = 0;
                try {
                    qty = Integer.parseInt(qtyStr);
                } catch (NumberFormatException e) {
                    qty = 0;
                }
                
                int ctn = 0;
                try {
                    ctn = Integer.parseInt(ctnStr);
                } catch (NumberFormatException e) {
                    ctn = 0;
                }
                
                int ctnPcs = 0;
                try {
                    ctnPcs = Integer.parseInt(ctnPcsStr);
                } catch (NumberFormatException e) {
                    ctnPcs = 0;
                }
                
                // 检查是否已存在（用于更新）
                Map<String, Object> existing = inventoryListMapper.selectInventoryExists(proId, ibNo, batchCode, palletNo, vndId, whId);
                
                if (existing != null && existing.get("id") != null) {
                    // 更新现有库存
                    Long existingId = ((Number) existing.get("id")).longValue();
                    Integer existingQty = existing.get("qty") != null ? ((Number) existing.get("qty")).intValue() : 0;
                    Integer existingOQty = existing.get("o_qty") != null ? ((Number) existing.get("o_qty")).intValue() : 0;
                    String existingRemarks = existing.get("remarks") != null ? existing.get("remarks").toString() : "";
                    
                    LxInventoryList inventory = inventoryListMapper.selectById(existingId);
                    if (inventory != null) {
                        // 与PHP逻辑一致：如果qty < 1 且 ctn > 0 且 ctnPcs > 0，则直接使用 ctn * ctnPcs（不累加）
                        if (qty < 1 && ctn > 0 && ctnPcs > 0) {
                            qty = ctn * ctnPcs;
                            inventory.setQty(qty);  // 直接设置，不累加（与PHP逻辑一致）
                            inventory.setOQty(qty); // 直接设置，不累加（与PHP逻辑一致）
                            inventory.setCtn(ctn);
                            inventory.setCtnPcs(ctnPcs);
                        } else {
                            // 累加数量（与PHP逻辑一致：$info['qty'] = intval($v[1])+intval($check_exists['qty']);）
                            inventory.setQty(existingQty + qty);
                            inventory.setOQty(existingOQty + qty);
                        }
                        
                        // 处理备注（与PHP逻辑一致：$info['remarks'] = $check_exists['remarks'].", ".trim($v[11]);）
                        if (!remarks.isEmpty()) {
                            if (!existingRemarks.isEmpty()) {
                                inventory.setRemarks(existingRemarks + ", " + remarks);
                            } else {
                                inventory.setRemarks(remarks);
                            }
                        }
                        
                        // 设置add_uid和add_time（与PHP逻辑一致）
                        inventory.setAddUid(userId != null ? userId.longValue() : null);
                        inventory.setAddTime(currentTime);
                        inventoryListMapper.updateById(inventory);
                    }
                } else {
                    // 新增库存
                    LxInventoryList inventory = new LxInventoryList();
                    inventory.setProId(proId);
                    inventory.setWhId(whId);
                    inventory.setVndId(vndId);
                    inventory.setIbNo(ibNo);
                    inventory.setPalletNo(palletNo);
                    inventory.setBatchCode(batchCode);
                    inventory.setIbRef(ibRef);
                    inventory.setRemarks(remarks);
                    inventory.setAddUid(userId != null ? userId.longValue() : null);
                    inventory.setAddTime(currentTime);
                    inventory.setIsOb(0);
                    
                    // 处理批次日期
                    if (!batchDateStr.isEmpty()) {
                        try {
                            // 尝试解析Excel日期
                            double excelDate = Double.parseDouble(batchDateStr);
                            Date batchDate = excelUtil.excelDateToJavaDate(excelDate);
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                            inventory.setBatchDate(sdf.format(batchDate));
                            Calendar cal = Calendar.getInstance();
                            cal.setTime(batchDate);
                            inventory.setBatchYear(cal.get(Calendar.YEAR));
                        } catch (NumberFormatException e) {
                            // 如果不是Excel日期格式，尝试直接解析日期字符串
                            try {
                                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                                Date batchDate = sdf.parse(batchDateStr);
                                inventory.setBatchDate(batchDateStr);
                                Calendar cal = Calendar.getInstance();
                                cal.setTime(batchDate);
                                inventory.setBatchYear(cal.get(Calendar.YEAR));
                            } catch (Exception ex) {
                                inventory.setIsFresh(6);
                            }
                        }
                    } else {
                        inventory.setIsFresh(6);
                    }
                    
                    // 如果qty < 1 且 ctn > 0 且 ctnPcs > 0，则使用 ctn * ctnPcs
                    if (qty < 1 && ctn > 0 && ctnPcs > 0) {
                        qty = ctn * ctnPcs;
                    }
                    
                    inventory.setQty(qty);
                    inventory.setOQty(qty);
                    inventory.setCtn(ctn);
                    inventory.setCtnPcs(ctnPcs);
                    
                    inventoryListMapper.insert(inventory);
                }
            }
            
            result.put("success", true);
            result.put("message", "Success");
            return result;
            
        } catch (Exception e) {
            log.error("导入库存失败", e);
            result.put("message", "导入失败: " + e.getMessage());
            return result;
        }
    }
    
    @Override
    public void exportInventoryList(HttpServletResponse response, Map<String, Object> params, boolean includeWarehouse, boolean includeBatchCode) {
        try {
            List<Map<String, Object>> list = inventoryListMapper.selectInventoryListByCondition(params);
            
            // 构建表头
            List<String> headers = new ArrayList<>();
            headers.add("Inbound#");
            headers.add("Pallets#");
            headers.add("Brand");
            headers.add("UPC");
            headers.add("Description(English)");
            headers.add("Description(Chinese)");
            headers.add("Qty");
            
            if (includeWarehouse) {
                headers.add("WH_REF");
            }
            
            headers.add("CTN");
            headers.add("CTN/PCS");
            
            if (includeWarehouse) {
                headers.add("VND");
            }
            
            if (includeBatchCode) {
                headers.add("Batch Code");
            }
            
            headers.add("Inbound Ref");
            
            // 创建工作簿
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("Sheet1");
            
            // 创建样式
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            
            // 创建表头
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.size(); i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers.get(i));
                cell.setCellStyle(headerStyle);
            }
            
            // 填充数据
            int rowNum = 1;
            for (Map<String, Object> row : list) {
                if (row == null) continue;
                
                Row dataRow = sheet.createRow(rowNum++);
                int colNum = 0;
                
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("ibNo")));
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("palletNo")));
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("brandName")));
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("eanCode")));
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("proNameEn")));
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("proNameCn")));
                dataRow.createCell(colNum++).setCellValue(getNumericValue(row.get("qty")));
                
                if (includeWarehouse) {
                    dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("whRef")));
                }
                
                dataRow.createCell(colNum++).setCellValue(getNumericValue(row.get("ctn")));
                dataRow.createCell(colNum++).setCellValue(getNumericValue(row.get("ctnPcs")));
                
                if (includeWarehouse) {
                    dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("vndRef")));
                }
                
                if (includeBatchCode) {
                    dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("batchCode")));
                }
                
                dataRow.createCell(colNum++).setCellValue(getStringValue(row.get("ibRef")));
            }
            
            // 自动调整列宽
            for (int i = 0; i < headers.size(); i++) {
                sheet.autoSizeColumn(i);
            }
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            String fileName = "Inventory_" + new SimpleDateFormat("yyyy_MM_dd").format(new Date());
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            
            // 写入响应流
            OutputStream outputStream = response.getOutputStream();
            workbook.write(outputStream);
            workbook.close();
            outputStream.close();
            
        } catch (Exception e) {
            log.error("导出库存列表失败", e);
            throw new RuntimeException("导出失败: " + e.getMessage());
        }
    }
    
    private String getStringValue(Object value) {
        return value != null ? value.toString() : "";
    }
    
    private double getNumericValue(Object value) {
        if (value == null) {
            return 0;
        }
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        try {
            return Double.parseDouble(value.toString());
        } catch (NumberFormatException e) {
            return 0;
        }
    }
    
    @Override
    public List<Map<String, Object>> getTransferInventoryList(Long fromWhId) {
        return inventoryListMapper.selectTransferInventoryList(fromWhId);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> createTransfer(Long fromWhId, Long toWhId, List<Map<String, Object>> transferItems, Integer userId) {
        Map<String, Object> result = new HashMap<>();
        
        if (fromWhId.equals(toWhId)) {
            result.put("success", false);
            result.put("message", "源仓库和目标仓库不能相同");
            return result;
        }
        
        if (transferItems == null || transferItems.isEmpty()) {
            result.put("success", false);
            result.put("message", "调拨明细不能为空");
            return result;
        }
        
        try {
            int currentTime = (int) (System.currentTimeMillis() / 1000);
            
            // 创建调拨单
            LxTransferList transfer = new LxTransferList();
            transfer.setFromWh(fromWhId);
            transfer.setToWh(toWhId);
            transfer.setTsfUid(userId != null ? userId.longValue() : null);
            transfer.setTsfTime(currentTime);
            transfer.setTotalQty(0);
            transfer.setIsRecvd(0);
            transferListMapper.insert(transfer);
            
            Long transferId = transfer.getId();
            int totalQty = 0;
            
            // 创建调拨明细
            for (Map<String, Object> item : transferItems) {
                Long inventoryId = Long.valueOf(item.get("inventoryId").toString());
                Integer qty = Integer.valueOf(item.get("qty").toString());
                
                if (qty <= 0) {
                    continue;
                }
                
                // 检查库存是否存在且数量足够
                LxInventoryList inventory = inventoryListMapper.selectById(inventoryId);
                if (inventory == null || !inventory.getWhId().equals(fromWhId)) {
                    throw new RuntimeException("库存记录不存在或不属于源仓库");
                }
                
                if (inventory.getQty() < qty) {
                    throw new RuntimeException("库存不足: 库存ID=" + inventoryId + ", 可用数量=" + inventory.getQty() + ", 需要数量=" + qty);
                }
                
                // 创建调拨明细
                LxTransferDetails detail = new LxTransferDetails();
                detail.setTsfId(transferId);
                detail.setInventoryId(inventoryId);
                detail.setProId(inventory.getProId());
                detail.setQty(qty);
                transferDetailsMapper.insert(detail);
                
                totalQty += qty;
            }
            
            // 更新调拨单总数量
            transfer.setTotalQty(totalQty);
            transferListMapper.updateById(transfer);
            
            result.put("success", true);
            result.put("message", "Success.");
            result.put("transferId", transferId);
            return result;
            
        } catch (Exception e) {
            log.error("创建调拨单失败", e);
            result.put("success", false);
            result.put("message", "创建调拨单失败: " + e.getMessage());
            return result;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean confirmTransfer(Long transferId, Integer userId) {
        try {
            // 获取调拨单
            LxTransferList transfer = transferListMapper.selectById(transferId);
            if (transfer == null) {
                throw new RuntimeException("调拨单不存在");
            }
            
            if (transfer.getIsRecvd() != null && transfer.getIsRecvd() == 1) {
                throw new RuntimeException("Error, already recvd");
            }
            
            // 获取调拨明细
            List<Map<String, Object>> details = inventoryListMapper.selectTransferDetailsByTsfId(transferId);
            
            // 验证库存是否足够
            for (Map<String, Object> detail : details) {
                Long inventoryId = ((Number) detail.get("inventoryId")).longValue();
                Integer qty = ((Number) detail.get("qty")).intValue();
                
                LxInventoryList inventory = inventoryListMapper.selectById(inventoryId);
                if (inventory == null) {
                    throw new RuntimeException("Error, Inventory not enought.");
                }
                
                if (inventory.getQty() < qty) {
                    throw new RuntimeException("Error, Inventory not enought.");
                }
            }
            
            // 执行调拨：减少源仓库库存，增加目标仓库库存
            int currentTime = (int) (System.currentTimeMillis() / 1000);
            
            for (Map<String, Object> detail : details) {
                Long inventoryId = ((Number) detail.get("inventoryId")).longValue();
                Integer qty = ((Number) detail.get("qty")).intValue();
                Long proId = ((Number) detail.get("proId")).longValue();
                
                // 减少源仓库库存
                LxInventoryList fromInventory = inventoryListMapper.selectById(inventoryId);
                fromInventory.setQty(fromInventory.getQty() - qty);
                fromInventory.setUpdateTime(currentTime);
                inventoryListMapper.updateById(fromInventory);
                
                // 检查目标仓库是否已有相同产品的库存
                QueryWrapper<LxInventoryList> wrapper = new QueryWrapper<>();
                wrapper.eq("wh_id", transfer.getToWh())
                        .eq("pro_id", proId)
                        .eq("batch_code", fromInventory.getBatchCode())
                        .eq("ib_no", fromInventory.getIbNo())
                        .eq("pallet_no", fromInventory.getPalletNo())
                        .eq("vnd_id", fromInventory.getVndId());
                
                LxInventoryList toInventory = inventoryListMapper.selectOne(wrapper);
                
                if (toInventory != null) {
                    // 更新现有库存
                    toInventory.setQty(toInventory.getQty() + qty);
                    toInventory.setUpdateTime(currentTime);
                    inventoryListMapper.updateById(toInventory);
                } else {
                    // 创建新库存记录
                    LxInventoryList newInventory = new LxInventoryList();
                    newInventory.setOlId(fromInventory.getOlId());
                    newInventory.setProId(fromInventory.getProId());
                    newInventory.setWhId(transfer.getToWh());
                    newInventory.setVndId(fromInventory.getVndId());
                    newInventory.setLocationId(fromInventory.getLocationId());
                    newInventory.setLocationCode(fromInventory.getLocationCode());
                    newInventory.setLocationSz(fromInventory.getLocationSz());
                    newInventory.setSlId(fromInventory.getSlId());
                    newInventory.setOrderNo(fromInventory.getOrderNo());
                    newInventory.setQty(qty);
                    newInventory.setOQty(qty);
                    newInventory.setCtns(fromInventory.getCtns());
                    newInventory.setCtnPcs(fromInventory.getCtnPcs());
                    newInventory.setCurrentCtn(fromInventory.getCurrentCtn());
                    newInventory.setBatchCode(fromInventory.getBatchCode());
                    newInventory.setBatchYear(fromInventory.getBatchYear());
                    newInventory.setBatchDate(fromInventory.getBatchDate());
                    newInventory.setIbNo(fromInventory.getIbNo());
                    newInventory.setPalletNo(fromInventory.getPalletNo());
                    newInventory.setIbRef(fromInventory.getIbRef());
                    newInventory.setRemarks(fromInventory.getRemarks());
                    newInventory.setIsOb(0);
                    newInventory.setAddUid(userId != null ? userId.longValue() : null);
                    newInventory.setAddTime(currentTime);
                    inventoryListMapper.insert(newInventory);
                }
            }
            
            // 更新调拨单状态
            transfer.setIsRecvd(1);
            transferListMapper.updateById(transfer);
            
            return true;
        } catch (Exception e) {
            log.error("确认调拨失败", e);
            throw new RuntimeException("确认调拨失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<Map<String, Object>> getTransferList(Map<String, Object> params) {
        return inventoryListMapper.selectTransferList(params);
    }
    
    @Override
    public Map<String, Object> getTransferDetail(Long transferId) {
        LxTransferList transfer = transferListMapper.selectById(transferId);
        if (transfer == null) {
            return null;
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("transfer", transfer);
        result.put("details", inventoryListMapper.selectTransferDetailsByTsfId(transferId));
        return result;
    }
    
    @Override
    public List<Map<String, Object>> getInventorySummary(Map<String, Object> params) {
        Integer view = (Integer) params.get("view");
        Long whId = params.get("whId") != null ? Long.valueOf(params.get("whId").toString()) : null;
        
        if (view != null && view == 1) {
            // 按装车单汇总
            return inventoryListMapper.selectInventorySummaryByLdId(whId);
        } else if (view != null && view == 2) {
            // 按订单汇总
            return inventoryListMapper.selectInventorySummaryByOrderId(whId);
        }
        
        return new ArrayList<>();
    }
    
    @Override
    public List<Map<String, Object>> getOverdueInventory(Map<String, Object> params) {
        return inventoryListMapper.selectOverdueInventory(params);
    }
}

